import 'package:flutter/material.dart';
import '../controllers/clean_calendar_controller.dart';
import '../models/day_values_model.dart';

class MonthsWidget extends StatelessWidget {
  final CleanCalendarController cleanCalendarController;
  final DateTime month;
  final double calendarCrossAxisSpacing;
  final double calendarMainAxisSpacing;
  final Widget Function(
    BuildContext context,
    DayValues values,
  )? dayBuilder;
  final Color? selectedBackgroundColor;
  final Color? backgroundColor;
  final Color? selectedBackgroundColorBetween;
  final Color? disableBackgroundColor;
  final Color? dayDisableColor;
  final double radius;
  final TextStyle? textStyle;
  final double? aspectRatio;

  const MonthsWidget({
    super.key,
    required this.month,
    required this.cleanCalendarController,
    required this.calendarCrossAxisSpacing,
    required this.calendarMainAxisSpacing,
    required this.dayBuilder,
    required this.selectedBackgroundColor,
    required this.backgroundColor,
    required this.selectedBackgroundColorBetween,
    required this.disableBackgroundColor,
    required this.dayDisableColor,
    required this.radius,
    required this.textStyle,
    required this.aspectRatio,
  });

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 4,
      physics: const NeverScrollableScrollPhysics(),
      addRepaintBoundaries: false,
      padding: EdgeInsets.zero,
      crossAxisSpacing: calendarCrossAxisSpacing,
      mainAxisSpacing: calendarMainAxisSpacing,
      shrinkWrap: true,
      childAspectRatio: aspectRatio ?? 1.4,
      children: List.generate(12, (index) {
        final day = DateTime(month.year, index + 1);

        bool isSelected = false;
        Widget widget;

        if (cleanCalendarController.rangeMinDate != null) {
          isSelected =
              day.isAtSameMomentAs(cleanCalendarController.rangeMinDate!);
        }

        final dayValues = DayValues(
          day: day,
          isFirstDayOfWeek: false,
          isLastDayOfWeek: false,
          isSelected: isSelected,
          maxDate: cleanCalendarController.maxDate,
          minDate: cleanCalendarController.minDate,
          text: '${index + 1}月',
          selectedMaxDate: cleanCalendarController.rangeMaxDate,
          selectedMinDate: cleanCalendarController.rangeMinDate,
        );

        if (dayBuilder != null) {
          widget = dayBuilder!(context, dayValues);
        } else {
          widget = _beauty(context, dayValues);
        }

        return GestureDetector(
          onTap: () {
            if (!(((day.year > cleanCalendarController.minDate.year) ||
                    ((day.year == cleanCalendarController.minDate.year) &&
                        (day.month >=
                            cleanCalendarController.minDate.month))) &&
                ((day.year < cleanCalendarController.maxDate.year) ||
                    ((day.year == cleanCalendarController.maxDate.year) &&
                        (day.month <=
                            cleanCalendarController.maxDate.month))))) {
              return;
            } else {
              if (!cleanCalendarController.readOnly) {
                cleanCalendarController.onDayClick(day);
              }
            }
          },
          child: widget,
        );
      }),
    );
  }

  Widget _beauty(BuildContext context, DayValues values) {
    Color bgColor = Colors.transparent;
    TextStyle txtStyle =
        (textStyle ?? Theme.of(context).textTheme.bodyLarge)!.copyWith(
      color: backgroundColor != null
          ? backgroundColor!.computeLuminance() > .5
              ? Colors.black
              : Colors.white
          : Theme.of(context).colorScheme.onSurface,
    );

    /// 选中
    if (values.isSelected) {
      bgColor = selectedBackgroundColorBetween ??
          Theme.of(context).colorScheme.primary.withOpacity(.3);
      txtStyle = (textStyle ?? Theme.of(context).textTheme.bodyLarge)!.copyWith(
        color: selectedBackgroundColor != null &&
                selectedBackgroundColor == selectedBackgroundColorBetween
            ? selectedBackgroundColor!.computeLuminance() > .5
                ? Colors.black
                : Colors.white
            : selectedBackgroundColor ?? Theme.of(context).colorScheme.primary,
      );
    }

    /// 范围之外
    else if (!(((values.day.year > values.minDate.year) ||
            ((values.day.year == values.minDate.year) &&
                (values.day.month >= values.minDate.month))) &&
        ((values.day.year < values.maxDate.year) ||
            ((values.day.year == values.maxDate.year) &&
                (values.day.month <= values.maxDate.month))))) {
      bgColor = disableBackgroundColor ??
          Theme.of(context).colorScheme.surface.withOpacity(.4);
      txtStyle = (textStyle ?? Theme.of(context).textTheme.bodyLarge)!.copyWith(
        color: dayDisableColor ??
            Theme.of(context).colorScheme.onSurface.withOpacity(.5),
      );
    }
    List<DateTime> tempList = [];
    for (var model in cleanCalendarController.haveDataTimeList) {
      tempList.add(DateTime(model.year, model.month));
    }
    return Container(
      alignment: Alignment.center,
      child: Container(
        padding: const EdgeInsets.only(top: 8, left: 8, right: 8),
        decoration: BoxDecoration(
          color: bgColor,
          borderRadius: BorderRadius.circular(5),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text(
              values.text,
              textAlign: TextAlign.center,
              style: txtStyle,
            ),
            if (tempList.contains(values.day))
              Container(
                width: 6.0,
                height: 6.0,
                decoration: BoxDecoration(
                  color: selectedBackgroundColor,
                  shape: BoxShape.circle,
                ),
              ),
            if (!tempList.contains(values.day))
              const SizedBox(
                width: 6,
                height: 6,
              ),
            const SizedBox(
              height: 2,
            )
          ],
        ),
      ),
    );
  }
}
